module nade.clipper;

import std.math;
import std.file;
import std.string;

import derelict.opengl.gl;
import derelict.opengl.glu;

import nade.vector;


scope class Clipper {
	this(Vector2 from, Vector2 to, bool intersect = false)
	{
		double[16] projection, modelview;
		int[4] view;

		glGetIntegerv(GL_SCISSOR_BOX, _oldBox.ptr);
		glGetDoublev(GL_MODELVIEW_MATRIX, modelview.ptr);
		glGetDoublev(GL_PROJECTION_MATRIX, projection.ptr);
		glGetIntegerv(GL_VIEWPORT, view.ptr);

		_oldBox[2] += _oldBox[0] - 1;
		_oldBox[3] += _oldBox[1] - 1;
		
		int[4] box = [ int.max, int.max, int.min, int.min ];
		void expandBox(double x, double y)
		{
			double wx, wy, wz;
			gluProject(x, y, 0.0, modelview.ptr, projection.ptr, view.ptr, &wx, &wy, &wz);

			if(wx < box[0]) box[0] = cast(int)floor(wx);
			if(wy < box[1]) box[1] = cast(int)floor(wy);
			if(wx > box[2]) box[2] = cast(int)ceil(wx);
			if(wy > box[3]) box[3] = cast(int)ceil(wy);
		}

		expandBox(from.x, from.y);
		// expandBox(from.x, to.y);
		// expandBox(to.x, from.y);
		expandBox(to.x, to.y);

		if(intersect)
		{
			if(box[0] < _oldBox[0]) box[0] = _oldBox[0];
			if(box[1] < _oldBox[1]) box[1] = _oldBox[1];
			if(box[2] > _oldBox[2]) box[2] = _oldBox[2];
			if(box[3] > _oldBox[3]) box[3] = _oldBox[3];
		}

		glPushAttrib(GL_SCISSOR_BIT);
		glEnable(GL_SCISSOR_TEST);
		glScissor(box[0], box[1], box[2] - box[0] + 1, box[3] - box[1] + 1);
	}

	~this()
	{
		glPopAttrib();
	}

	private {
		int[4]			_oldBox;
	}
}
